package com.sduept.nwld.dataserver.controller.fault;

import com.sduept.bigdata.fault.entity.TravelingWaveFaultRecord;
import com.sduept.bigdata.fault.manager.TravelingFaultRecordQueryManager;
import com.sduept.bigdata.fault.manager.WaveFileAssistManager;
import com.sduept.bigdata.fault.system.properties.FaultSystemProperties;
import com.sduept.core.entity.IdentifiedObject;
import com.sduept.generator.ObjectId;
import com.sduept.nwld.dataserver.controller.daily.DailyReportAbstractController;
import com.sduept.utils.DateUtil;
import com.sduept.utils.ZipUtil;

import org.apache.commons.lang.StringUtils;

import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 行波故障管理
 * @author lixz
 * @date 2020.7.1 
 */
@Named
@ViewScoped
public class TravelingWaveFaultController extends DailyReportAbstractController {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1853237474851286269L;
	/**
	 * 故障表格展示--表格懒加载模型
	 */
	private LazyDataModel<TravelingWaveFaultRecord> listsModel;
	/**
	 * 表格数据
	 */
	private List<TravelingWaveFaultRecord> faultLists; 
	/**
	 * 表数据量
	 */
	private int count;
	/**
	 * 表格选择数据
	 */
	private List<TravelingWaveFaultRecord> selectFaults = null; 

	/**
	 * 查询条件--故障设备名称
	 */
	private String faultDevice = ""; 
	private String faultDeviceId = ""; 
	/**
	 * .行波文件
	 */
	private StreamedContent file;
	
	@Autowired
	private TravelingFaultRecordQueryManager travelingFaultRecordQueryManager;
	@Autowired
	private FaultSystemProperties pros;
	
	private static final String linux_separator = "/";
	public static final String FILE_FORMAT_CFG = "cfg";
	public static final String FILE_FORMAT_DAT = "dat";

	@PostConstruct
	public void init() {
		query();
	}
	/**
	 * 懒加载查询数据
	 */
	private void lazyQueryTable() {
		
		listsModel = new LazyDataModel<TravelingWaveFaultRecord>() {
			
			private static final long serialVersionUID = -917176743366310962L;

			@Override
			public List<TravelingWaveFaultRecord> load(int first, int pageSize, String sortField, SortOrder sortOrder,
					Map<String, Object> filters) {
				Object[] ps = getQueryParamter();
				int[] range = new int[] { first, first + pageSize };
				if(StringUtils.isNotEmpty(faultDeviceId)) {
					faultLists = travelingFaultRecordQueryManager.getFaultRecordByDateDeviceId((Date)ps[0],(Date)ps[1], faultDeviceId,range);
				}else {
					faultLists = travelingFaultRecordQueryManager.getFaultRecordByDate((Date)ps[0],(Date)ps[1],range);
				}
				return faultLists;
			}

			@Override
			public TravelingWaveFaultRecord getRowData(String rowKey) {
				for (TravelingWaveFaultRecord t : faultLists) {
					if (t.getId().equals(rowKey)) {
						return t;
					}
				}
				return null;
			}

			@Override
			public Object getRowKey(TravelingWaveFaultRecord object) {
				for (TravelingWaveFaultRecord t : faultLists) {
					if (t.getId().equals(object.getId())) {
						return t;
					}
				}
				return null;
			}
		};
		
		if(faultLists==null || faultLists.size()==0 ) {
			Object[] ps = getQueryParamter();
			if(StringUtils.isNotEmpty(faultDeviceId)) {
				faultLists = travelingFaultRecordQueryManager.getFaultRecordByDateDeviceId((Date)ps[0],(Date)ps[1], faultDeviceId);
			}else {
				faultLists = travelingFaultRecordQueryManager.getFaultRecordByDate((Date)ps[0],(Date)ps[1]);
			}
			count = faultLists.size();
		}else {
			count = faultLists.size();
		}
		listsModel.setRowCount((int) count);
	}
	
	/**
	 * 查询列表数据
	 */
	public void query() {
		if (queryDate1 == null) {
			queryDate1 = new Date(0);
		}
		if (queryDate2 == null) {
			queryDate2 = new Date();
		}
		if (faultLists != null) {
			faultLists.clear();
		}
		refreshQueryParamter();
		lazyQueryTable();
	}
	
	/**
	 * 重置按钮调用方法
	 */
	public void resetQuery() {
		queryDate1 = null;
		queryDate2 = null;
		resetqueryDate();
		faultDevice = ""; 
		faultDeviceId = ""; 
		faultLists.clear();
		query();
	}
	
	public void prepareDownload(String travelFaultId){
		System.out.println("travelFaultId:"+travelFaultId);
		file = dowloadTravelingFile(travelFaultId);
		if(file == null) {
			addErrorMessage("查找文件失败，无法下载");
		}else {
			addErrorMessage("查找文件成功");
		}
	}
	
	/**
	 * .【行波下载】
	 * .根据行波故障id,下载相应的行波文件
	 * @param travelingWaveFaultRecordId
	 * @return
	 */
	public StreamedContent dowloadTravelingFile(String travelingWaveFaultRecordId) {
		TravelingWaveFaultRecord travelingWaveFaultRecord = travelingFaultRecordQueryManager.getTravelingWaveFaultRecordById(travelingWaveFaultRecordId);
		if(travelingWaveFaultRecord == null) {
			return null;
		}
		String tmpFileName = ObjectId.get().toString();
		Boolean local = generateStationTravelingFileByZip(tmpFileName,travelingWaveFaultRecord.getLocalXbFileName(),travelingWaveFaultRecord.getLocalStationName());
		Boolean peer = generateStationTravelingFileByZip(tmpFileName,travelingWaveFaultRecord.getPeerXbFileName(),travelingWaveFaultRecord.getPeerStationName());
		if(local||peer) {
			List<File> list = new ArrayList<File>();
	        String filePath = pros.getDownloadTmPath() +linux_separator+tmpFileName;
	        String zipPath = filePath + ".zip";
			File file = new File(filePath);
			list.add(file);
			ZipUtil.zipFile(filePath, list);
			//删除文件夹
			ZipUtil.deletefile(filePath);
			//获取zip文件
			InputStream stream = null;
			DefaultStreamedContent fileStreamed = null;
			try {
				stream = new FileInputStream(new File(zipPath));
				fileStreamed = new DefaultStreamedContent(stream, "application/octet-stream", tmpFileName + ".zip");
				new DeleteThread(zipPath).start();
				
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			return fileStreamed;
		}else {
			return null;
		}
	}
	/**
	 * .【行波下载】
	 * .获取要压缩的文件，并放到指定格式的的文件夹下
	 * @param tmpFileName ：压缩文件夹名
	 * @param travelingFileName ：行波文件名
	 * @param stationName ：变电站名
	 * @return
	 */
	private Boolean generateStationTravelingFileByZip(String tmpFileName,String travelingFileName,String stationName) {
		if(StringUtils.isEmpty(pros.getTRAVELING_FILE_PATH())) {
			System.out.println("未配置行波文件下载路径");
			return false;
		}
		if(StringUtils.isEmpty(travelingFileName)) {
			System.out.println("行波文件名称为空");
			return false;
		}
		if(StringUtils.isEmpty(stationName)) {
			System.out.println("行波文件所属变电站名称为空");
			return false;
		}
		//临时存储路径
		String tempDir = pros.getDownloadTmPath() + tmpFileName +linux_separator+ stationName + linux_separator + travelingFileName;
		File baseDir = new File(tempDir);		
		if (!baseDir.exists()){
			baseDir.mkdirs();
		}
		if(baseDir.exists()) {
			//下载路径
			File baseDirDownload = new File(pros.getTRAVELING_FILE_PATH());
			File[] files = baseDirDownload.listFiles();
			if(files == null || files.length==0){
				System.out.println("配置的路径下的文件夹为空文件夹");
				return false;
			}
			for (File file : files) {
				if(file.getName().equals(travelingFileName+".cfg")){
					try {
						File Des = new File(tempDir+linux_separator+travelingFileName+".cfg");
						Files.copy(file.toPath(), Des.toPath());
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(file.getName().equals(travelingFileName+".dat")){
					try {
						File Des = new File(tempDir+linux_separator+travelingFileName+".dat");
						Files.copy(file.toPath(), Des.toPath());
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if(file.getName().equals(travelingFileName+".hdr")){
					try {
						File Des = new File(tempDir+linux_separator+travelingFileName+".hdr");
						Files.copy(file.toPath(), Des.toPath());
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			return true;
		}
		return false;
	}
	private class DeleteThread extends Thread {
		String tempPath = "";

		DeleteThread(String tempPath) {
			this.tempPath = tempPath;
		}

		@Override
		public void run() {
			boolean flag = true;
			while (flag) {
				File f = new File(tempPath);
				if (f.exists()) {
					f.delete();
				} else {
					flag = false;
				}
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 查询参数设置
	 * @return
	 */
	private Object[] getQueryParamter() {
		String dayStart = DateUtil.getStringDate(queryDate1, DateUtil.pattern_ymd) + " 00:00:00";
		String dayEnd = DateUtil.getStringDate(queryDate2, DateUtil.pattern_ymd) + " 23:59:59";
		Date startTime = DateUtil.getDateByString(dayStart, DateUtil.pattern_ymdhms);
		Date endTime = DateUtil.getDateByString(dayEnd, DateUtil.pattern_ymdhms);
		return new Object[] { startTime, endTime};
	}
	
	/**
	 * 时间选择器start
	 * @param popup1
	 */
	public void onDateSelectStart(SelectEvent popup1) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		facesContext.addMessage(null,
				new FacesMessage(FacesMessage.SEVERITY_INFO, "Date Selected", format.format(popup1.getObject())));
	}
	
    /**
           * 时间选择器end
     * @param popup2
     */
	public void onDateSelectEnd(SelectEvent popup2) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		facesContext.addMessage(null,
				new FacesMessage(FacesMessage.SEVERITY_INFO, "Date Selected", format.format(popup2.getObject())));
	}
	
	/**
	 * 打开选择设备模态框
	 */
	public void getEquipmentByStation() {
		Map<String, Object> options = new HashMap<String, Object>();
		options.put("resizable", true);
		options.put("draggable", true);
		options.put("modal", true);
		options.put("width", 600);
		options.put("height", 400);
		Map<String, List<String>> params = new HashMap<>();
		params.put("chooseStation", Arrays.asList("false"));
//		RequestContext.getCurrentInstance().openDialog("/ui/common/equipment_selector_single", options, params);
		String url = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath()+"/ui/common/equipment_selector_single";
	    openDialog("/ui/common/equipment_selector_single", params, options);
	}
	
	/**
	 * 故障设备选择
	 */
	public void onFaultDeviceChosen(SelectEvent event) {
		IdentifiedObject equipment = (IdentifiedObject) event.getObject();
		faultDevice = equipment.getName();
		faultDeviceId = equipment.getId();
	}

	public String getFaultDevice() {
		return faultDevice;
	}

	public void setFaultDevice(String faultDevice) {
		this.faultDevice = faultDevice;
	}

	public String getFaultDeviceId() {
		return faultDeviceId;
	}
	public void setFaultDeviceId(String faultDeviceId) {
		this.faultDeviceId = faultDeviceId;
	}
	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public LazyDataModel<TravelingWaveFaultRecord> getListsModel() {
		return listsModel;
	}

	public void setListsModel(LazyDataModel<TravelingWaveFaultRecord> lineFaultsModel) {
		this.listsModel = lineFaultsModel;
	}

	public List<TravelingWaveFaultRecord> getSelectFaults() {
		return selectFaults;
	}

	public void setSelectFaults(List<TravelingWaveFaultRecord> selectFaults) {
		this.selectFaults = selectFaults;
	}
	public StreamedContent getFile() {
		return file;
	}
	public void setFile(StreamedContent file) {
		this.file = file;
	}

}
